package concurrent.cas;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

/**
 * @author LoneRanger
 * @version 1.0
 */
public class LongAdderTest {


	public static void main(String[] args) {
		testAtomicLongVSLongAdder(10, 10000);
		System.out.println("==================");
		testAtomicLongVSLongAdder(10, 200000);
		System.out.println("==================");
		testAtomicLongVSLongAdder(100, 200000);
	}

	static void testAtomicLongVSLongAdder(final int threadCount, final int times) {
		try {
			long start = System.currentTimeMillis();
			testLongAdder(threadCount, times);
			long end = System.currentTimeMillis() - start;
			System.out.println("条件>>>>>>线程数:" + threadCount + ", 单线程操作计数" + times);
			System.out.println("结果>>>>>>LongAdder方式增加计数" + (threadCount * times) + "次,共计耗时:" + end);

			long start2 = System.currentTimeMillis();
			testAtomicLong(threadCount, times);
			long end2 = System.currentTimeMillis() - start2;
			System.out.println("条件>>>>>>线程数:" + threadCount + ", 单线程操作计数" + times);
			System.out.println("结果>>>>>>AtomicLong方式增加计数" + (threadCount * times) + "次,共计耗时:" + end2);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	static void testAtomicLong(final int threadCount, final int times) throws InterruptedException {
		CountDownLatch countDownLatch = new CountDownLatch(threadCount);
		AtomicLong atomicLong = new AtomicLong();
		for (int i = 0; i < threadCount; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					for (int j = 0; j < times; j++) {
						atomicLong.incrementAndGet();
					}
					countDownLatch.countDown();
				}
			}, "my-concurrent.thread" + i).start();
		}
		countDownLatch.await();
	}

	static void testLongAdder(final int threadCount, final int times) throws InterruptedException {
		CountDownLatch countDownLatch = new CountDownLatch(threadCount);
		LongAdder longAdder = new LongAdder();
		for (int i = 0; i < threadCount; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					for (int j = 0; j < times; j++) {
						longAdder.add(1);
					}
					countDownLatch.countDown();
				}
			}, "my-concurrent.thread" + i).start();
		}

		countDownLatch.await();
	}
}
